﻿using IdentityModel.Client;
using IdentityServer.Dtos;
using Microsoft.AspNetCore.Mvc;

namespace IdentityServer.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class IdentityServerController : Controller
    {
        private readonly HttpClient _httpClient;
        private readonly DiscoveryDocumentResponse _discoveryDocumentResponse;
        private static readonly object Lock = new object();

        public IdentityServerController(HttpClient httpClient, IConfiguration configuration)
        {
            _httpClient = httpClient;
            _discoveryDocumentResponse = _httpClient.GetDiscoveryDocumentAsync(configuration["GateWay:AuthUri"]).Result;
            if(_discoveryDocumentResponse.IsError)
            {
                throw new Exception("未知错误!");
            }
        }        

        /// <summary>
        /// 内部服务调用鉴权认证--客户端
        /// </summary>
        /// <returns></returns>
        [HttpPost("Client")]
        public ReturnResult<TokenOutput> GetClientAuth([FromBody] TokenInput input)
        {
            Console.WriteLine("Client");
            lock (Lock)
            {
                try
                {
                    if(string.IsNullOrEmpty(input.UserCode) || string.IsNullOrEmpty(input.Password))
                    {
                        throw new Exception("用户名或密码不能为空!");
                    }

                    var tokenClient = new TokenClient(_httpClient, new TokenClientOptions
                    {
                        Address = _discoveryDocumentResponse.TokenEndpoint,
                        ClientId = input.UserCode.Trim(),
                        ClientSecret = input.Password.Trim()
                    });

                    var tokenResponse = tokenClient.RequestClientCredentialsTokenAsync().Result;
                    if (tokenResponse.IsError)
                    {
                        throw new Exception("用户名或密码错误!");
                    }
                    return ReturnResult<TokenOutput>.Success(new TokenOutput
                    {
                        AccessToken = tokenResponse.AccessToken,
                        RefreshToken = tokenResponse.RefreshToken,
                        Expiration = tokenResponse.ExpiresIn
                    });
                }
                catch (Exception ex)
                {
                    return ReturnResult<TokenOutput>.Failed(ex.Message);
                }
            }
        }

        /// <summary>
        /// 账户密码鉴权认证
        /// </summary>
        /// <returns></returns>
        [HttpPost("Pwd")]
        public ReturnResult<TokenOutput> GetPwdAuth([FromBody] TokenInput input)
        {
            Console.WriteLine("Pwd");
            lock (Lock)
            {
                try
                {
                    if (string.IsNullOrEmpty(input.UserCode) || string.IsNullOrEmpty(input.Password))
                    {
                        throw new Exception("用户名或密码不能为空!");
                    }

                    var tokenClient = new TokenClient(_httpClient, new TokenClientOptions
                    {
                        Address = _discoveryDocumentResponse.TokenEndpoint,
                        ClientId = "pwd",
                        ClientSecret = "secret"
                    });
                    var tokenResponse = tokenClient.RequestPasswordTokenAsync(input.UserCode.Trim(), input.Password.Trim()).Result;
                    if (tokenResponse.IsError)
                    {
                        throw new Exception("用户名或密码错误!");
                    }
                    return ReturnResult<TokenOutput>.Success(new TokenOutput
                    {
                        AccessToken = tokenResponse.AccessToken,
                        RefreshToken = tokenResponse.RefreshToken,
                        Expiration = tokenResponse.ExpiresIn
                    });
                }
                catch (Exception ex)
                {
                    return ReturnResult<TokenOutput>.Failed(ex.Message);
                }
            }
        }

        /// <summary>
        /// 刷新token认证
        /// </summary>
        /// <returns></returns>
        [HttpGet("Refresh")]
        public ReturnResult<TokenOutput> RefreshToken([FromQuery] string refreshToken)
        {
            Console.WriteLine("Refresh");
            lock (Lock)
            {
                try
                {
                    if (string.IsNullOrEmpty(refreshToken))
                    {
                        throw new Exception("refreshToken不能为空!");
                    }

                    var tokenClient = new TokenClient(_httpClient, new TokenClientOptions
                    {
                        Address = _discoveryDocumentResponse.TokenEndpoint,
                        ClientId = "pwd",
                        ClientSecret = "secret"
                    });

                    var tokenResponse = tokenClient.RequestRefreshTokenAsync(refreshToken).Result;
                    if (tokenResponse.IsError)
                    {
                        throw new Exception("refreshToken已失效!");
                    }
                    return ReturnResult<TokenOutput>.Success(new TokenOutput
                    {
                        AccessToken = tokenResponse.AccessToken,
                        RefreshToken = tokenResponse.RefreshToken,
                        Expiration = tokenResponse.ExpiresIn
                    });
                }
                catch (Exception ex)
                {
                    return ReturnResult<TokenOutput>.Failed(ex.Message);
                }
            }
        }
    }
}
